import Stack from 'react-native-card-stack-swiper';

import {
    Animated,
    Dimensions,
    PanResponder,
    Platform,
    StyleSheet,
    Text,
    View
} from 'react-native';
import PropTypes from "prop-types";

const {
    height,
    width
} = Dimensions.get('window');

Stack.defaultProps.onSwipedAll = () => {}

export default class CardStack extends Stack {
    cardFns = [];

    static childContextTypes = {
        cardMove: PropTypes.func,
        unCardMove: PropTypes.func
    }

    getChildContext() {
        return {
            cardMove: this.addCardMoveFn,
            unCardMove: this.removeCardMoveFn
        }
    }

    addCardMoveFn = fn => {
        this.cardFns.push(fn);
    }

    removeCardMoveFn = fn => {
        const index = this.cardFns.findIndex(f => f === fn);
        this.cardFns.splice(index, 1);
    }

    _moveAction = pos => {
        this.cardFns.forEach(fn => fn(
            pos,
            this.state.sindex - 2
        ))
    }

    componentWillMount() {
        this._panResponder = PanResponder.create({
            onShouldBlockNativeResponder: () => true,
            onStartShouldSetPanResponder: () => false,
            onPanResponderTerminationRequest: () => true,
            onStartShouldSetPanResponderCapture: () => false,
            onMoveShouldSetPanResponder: (evt, gestureState) => {
                const isVerticalSwipe = Math.sqrt(
                    Math.pow(gestureState.dx, 2) < Math.pow(gestureState.dy, 2)
                )
                if (!this.props.verticalSwipe && isVerticalSwipe) {
                    return false
                }
                return Math.sqrt(
                    Math.pow(gestureState.dx, 2) + Math.pow(gestureState.dy, 2)
                ) > 10
            },
            onMoveShouldSetPanResponderCapture: (evt, gestureState) => {
                const isVerticalSwipe = Math.sqrt(
                    Math.pow(gestureState.dx, 2) < Math.pow(gestureState.dy, 2)
                )
                if (!this.props.verticalSwipe && isVerticalSwipe) {
                    return false
                }
                return Math.sqrt(
                    Math.pow(gestureState.dx, 2) + Math.pow(gestureState.dy, 2)
                ) > 10
            },
            onPanResponderGrant: () => {
                this.setState({touchStart: new Date().getTime()});
            },
            onPanResponderMove: (evt, gestureState) => {
                const {
                    onSwipedAll,
                    verticalSwipe,
                    horizontalSwipe
                } = this.props;
                const dragDistance = this.distance(
                    (horizontalSwipe) ? gestureState.dx : 0,
                    (verticalSwipe) ? gestureState.dy : 0
                )
                this.state.dragDistance.setValue(dragDistance)
                const moveX = (horizontalSwipe) ? gestureState.dx : 0;
                const moveY = (verticalSwipe) ? gestureState.dy : 0;
                const pos = {
                    x: moveX,
                    y: moveY
                }
                this.state.drag.setValue(pos)
                onSwipedAll(pos)
                this._moveAction(pos)
            },
            onPanResponderRelease: (evt, gestureState) => {
                const currentTime = new Date().getTime();
                const swipeDuration = currentTime - this.state.touchStart;
                const {
                    onSwipedAll,
                    verticalThreshold,
                    horizontalThreshold,
                    disableTopSwipe,
                    disableLeftSwipe,
                    disableRightSwipe,
                    disableBottomSwipe,
                } = this.props;
                onSwipedAll({
                    x: 0,
                    y: 0
                })
                this._moveAction({
                    x: 0,
                    y: 0
                })
                if (((Math.abs(gestureState.dy) > verticalThreshold) ||
                    (Math.abs(gestureState.dy) > verticalThreshold * 0.8 &&
                        swipeDuration < 150)
                ) && this.props.verticalSwipe) {

                    const swipeDirection = (gestureState.dy < 0) ? height * -1 : height;
                    if (swipeDirection < 0 && !disableTopSwipe) {

                        this._nextCard('top', gestureState.dx, swipeDirection, this.props.duration);
                    }
                    else if (swipeDirection > 0 && !disableBottomSwipe) {
                        this._nextCard('bottom', gestureState.dx, swipeDirection, this.props.duration);
                    }
                    else {
                        this._resetCard();
                    }
                } else if (((Math.abs(gestureState.dx) > horizontalThreshold) ||
                    (Math.abs(gestureState.dx) > horizontalThreshold * 0.6 &&
                        swipeDuration < 150)
                ) && this.props.horizontalSwipe) {

                    const swipeDirection = (gestureState.dx < 0) ? width * -1 : width;
                    if (swipeDirection < 0 && !disableLeftSwipe) {
                        this._nextCard('left', swipeDirection, gestureState.dy, this.props.duration);
                    }
                    else if (swipeDirection > 0 && !disableRightSwipe) {
                        this._nextCard('right', swipeDirection, gestureState.dy, this.props.duration);
                    }
                    else {
                        this._resetCard();
                    }
                }
                else {
                    this._resetCard();
                }
            }
        });
    }

    render() {
        return super.render()
    }
}